# vga.s
# connect4-nios2 project
#
# vga drawing functions
#
# Michael Michniewski 2009 

.equ VGA_ADDR, 0xa00000

# board size parameters
.equ board_piece_size, 10
.equ board_piece_spacing, 2
.equ board_left_offset, 25
.equ board_top_offset, 20

.data

.global VGA_BLANK_SCREEN
.global VGA_DRAW_BOX
.global VGA_PUT_PIXEL
.text

VGA_BLANK_SCREEN:
	# put black everywhere

	subi sp, sp, 4
	stw ra, 0(sp)

	movia r8, VGA_ADDR
	
	movi r6, 0b000	# black
	movi r4, 0		# x-counter
	movi r5, 0		# y-counter
	movi r11, 160	# x-bound
	movi r12, 120	# y-bound

	BLK_LOOPY:
		BLK_LOOPX:
			beq r4, r11, BLK_DONE_X	# while
				subi sp, sp, 12
				stw r4, 0(sp)
				stw r5, 4(sp)
				stw r6, 8(sp)
			call VGA_PUT_PIXEL
				ldw r6, 8(sp)
				ldw r5, 4(sp)
				ldw r4, 0(sp)
				addi sp, sp, 12
			addi r4, r4, 1	# increment x
			br BLK_LOOPX
		BLK_DONE_X:
	movi r4, 0
	beq r5, r12, BLK_DONE_Y	# while
	addi r5, r5, 1	# increment x
	br BLK_LOOPY
	BLK_DONE_Y:

	ldw ra, 0(sp)
	addi sp, sp, 4
	ret

VGA_DRAW_BOX:
	# draw box
	# start x	- r4
	# start y	- r5
	# end x	- r6
	# end y	- r7
	# colour	- sp

	ldw r13, 0(sp)	# load colour from stack

	subi sp, sp, 20	# save ra
	stw ra, 0(sp)
	stw r9, 4(sp)
	stw r10, 8(sp)
	stw r11, 12(sp)
	stw r12, 16(sp)

	movia r8, VGA_ADDR
	
	mov r9, r4		# x-counter
	mov r10, r5		# y-counter
	mov r11, r6		# x-bound
	mov r12, r7		# y-bound

	BX_LOOPY:
		BX_LOOPX:
			beq r9, r11, BX_DONE_X	# while
				subi sp, sp, 20
				stw r4, 0(sp)
				stw r5, 4(sp)
				stw r6, 8(sp)
				stw r7, 12(sp)
				stw r8, 16(sp)

				mov r4, r9		# send the current pixel (x, y), colour
				mov r5, r10
				mov r6, r13
			call VGA_PUT_PIXEL

				ldw r8, 16(sp)
				ldw r7, 12(sp)
				ldw r6, 8(sp)
				ldw r5, 4(sp)
				ldw r4, 0(sp)
				addi sp, sp, 20
			addi r9, r9, 1	# increment x
			br BX_LOOPX
		BX_DONE_X:
	mov r9, r4
	beq r10, r12, BX_DONE_Y	# while
	addi r10, r10, 1	# increment x
	br BX_LOOPY
	BX_DONE_Y:

	ldw r9, 4(sp)
	ldw r10, 8(sp)
	ldw r11, 12(sp)
	ldw r12, 16(sp)
	ldw ra, 0(sp)
	addi sp, sp, 20
	ret


VGA_PUT_PIXEL:
	# r4 - x, r5 - y, r6 - colour

	subi sp, sp, 4
	stw ra, 0(sp)

	movia r7, VGA_ADDR
	# fix x
	andi r4, r4, 0xff		# 8 bits for x
	slli r4, r4, 2
	#fix y
	andi r5, r5, 0b01111111	# 7  bits for y
	slli r5, r5, 10
	# fix colour
	andi r6, r6, 0b111
	# offset from address
	add r7, r7, r4
	add r7, r7, r5
	# write to vga
	stwio r6, 0(r7)

	ldw ra, 0(sp)
	addi sp, sp, 4
	ret
